package rerac.components;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import rerac.feature.DocumentExtractor;

import goalie.Component;

/**
 * This retrieves documents from a Lucene index on document protocol buffers.
 * Retrieval is done on the "contents" field, i.e. the token text.
 * 
 * Input parameters:
 * "index": The directory of the index.
 * "query": A string query for which the index is searched for.
 * 
 * Output parameters:
 * NONE
 * 
 * @author Benjamin Roth
 *
 */
public class RetrieveDocuments implements Component {
  
  public static final String REFERRED_NAME = "retrieve_documents";

  @Override
  public Map<String, String> run(Map<String, String> params) throws IOException {
    String indexDir = params.get("index");
    String q = params.get("query");
    
    Directory dir = FSDirectory.open(new File(indexDir));
    IndexSearcher is = new IndexSearcher(dir, true);

    QueryParser parser = new QueryParser(Version.LUCENE_29, "contents", 
        new WhitespaceAnalyzer());
    Query query;
    try {
      query = parser.parse(q);
      long start = System.currentTimeMillis();
      TopDocs hits = is.search(query, 10); //5
      long end = System.currentTimeMillis();
      
      System.err.println("Found " + hits.totalHits +
      " document(s) (in " + (end - start) +
      " milliseconds) that matched query '" +
      q + "':");
      
      for(int i=0; i < hits.scoreDocs.length; i++) {
        ScoreDoc scoreDoc = hits.scoreDocs[i];
        Document luceneDoc = is.doc(scoreDoc.doc);
        System.out.println(luceneDoc.get("id"));
        
        String fn = luceneDoc.get("filename");
        System.out.println(fn);
        FileInputStream fis = new FileInputStream(fn);
        long offset = Long.parseLong(luceneDoc.get("offset"));
        System.out.println("Offset: " + offset);
        fis.skip(offset);
        BufferedInputStream bis = new BufferedInputStream(fis);
        rerac.protos.Corpus.Document doc = 
            rerac.protos.Corpus.Document.parseDelimitedFrom(bis);
        bis.close();
        System.out.println(DocumentExtractor.textFromTokens(doc, " "));
        System.out.println();

      }
    } catch (ParseException e) {
      e.printStackTrace();
    }
    is.close();
    return new HashMap<String, String>();
  }

  @Override
  public void cleanup(Map<String, String> outputs) throws IOException {
  }

}
